package com.optitronics.controllers;

import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.support.GenericConversionService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import com.optitronics.beans.OrderItem;
import com.optitronics.beans.Product;
import com.optitronics.beans.Reseller;
import com.optitronics.beans.ResellerOrder;
import com.optitronics.service.ReportService;
import com.optitronics.service.UserService;
import com.optitronics.ui.ResellerOrderDisplayForm;
import com.optitronics.util.OptitronicsConstants;
import com.optitronics.util.OptitronicsUtils;

@RequestMapping("/resellerorders")
@Controller
public class ResellerOrderController {

	@Autowired
	private GenericConversionService conversionService;

	@Autowired
	private ReportService reportService;

	@Autowired
	private UserService userService;

	@RequestMapping(value = "/{id}", method = RequestMethod.GET)
	public String show(@PathVariable("id") Integer id, @RequestParam(value = "saved", required = false) Boolean saved,
			Model model) {

		userService.checkUserResellerOrder(id);

		ResellerOrderDisplayForm formObj = new ResellerOrderDisplayForm(ResellerOrder.findResellerOrder(id));
		List<OrderItem> orderItems = OrderItem.findOrderItems(id);
		model.addAttribute("resellerorder", formObj);
		model.addAttribute("itemId", id);
		model.addAttribute("saved", saved);
		model.addAttribute("orderItems", orderItems);

		return "resellerorders/show";
	}

	@RequestMapping(value = "/orderItem/{orderItemId}", method = RequestMethod.GET)
	public String showByOrderItemId(@PathVariable("orderItemId") Integer orderItemId, Model model) {
		OrderItem orderItem = OrderItem.findOrderItem(orderItemId);

		return "redirect:/resellerorders/" + orderItem.getResellerOrder().getId();
	}

	@RequestMapping(value = "/{orderId}/print")
	public String printResellerOrder(@PathVariable("orderId") Integer orderId, Model model, HttpServletRequest request) {

		String applicationFolder = request.getSession().getServletContext().getRealPath("/");

		userService.checkUserResellerOrder(orderId);
		Map<String, Object> reportParams = reportService.printInvoiceReport(orderId, applicationFolder);
		model.addAllAttributes(reportParams);

		return "invoiceReport";
	}

	@RequestMapping(value = "/reseller/{resellerId}")
	public String showResellerOrders(@PathVariable("resellerId") Integer resellerId, Model model) {
		model.addAttribute("owner", resellerId);
		model.addAttribute("size", OptitronicsConstants.PAGE_SIZE);
		model.addAttribute("page", 1);

		return "redirect:/resellerorders";
	}

	@RequestMapping(method = RequestMethod.GET)
	public String list(@RequestParam("page") Integer page, @RequestParam("size") Integer size,
			@RequestParam(value = "owner", required = false) Integer owner, Model model) {

		userService.checkUserResellerOrders(owner);

		if (OptitronicsUtils.isUserReseller()) {
			Reseller reseller = Reseller.findResellerByEmail(OptitronicsUtils.getActiveUser());
			owner = reseller.getId();
		}

		int sizeNo = size == null ? OptitronicsConstants.PAGE_SIZE : size.intValue();
		model.addAttribute("resellerorders",
				ResellerOrder.findResellerOrderEntries(owner, (page.intValue() - 1) * sizeNo, sizeNo));
		float nrOfPages = (float) ResellerOrder.countResellerOrders(owner) / sizeNo;
		model.addAttribute("maxPages", (int) ((nrOfPages > (int) nrOfPages || nrOfPages == 0.0) ? nrOfPages + 1
				: nrOfPages));

		return "resellerorders/list";
	}

	Converter<Product, String> getProductConverter() {
		return new Converter<Product, String>() {
			public String convert(Product product) {
				return new StringBuilder().append(product.getName()).toString();
			}
		};
	}

	@PostConstruct
	void registerConverters() {
		conversionService.addConverter(getProductConverter());
	}

}
